package api

import (
	"aifuture.cloud/models"
	"aifuture.cloud/pkg/app"
	"aifuture.cloud/pkg/e"
	"aifuture.cloud/pkg/gredis"
	"aifuture.cloud/pkg/setting"
	"aifuture.cloud/pkg/util"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/spf13/cast"
	"time"
)

// 用户注册
type RegisterReq struct {
	Username  string `json:"username" binding:"required"`   //用户名
	Password  string `json:"password" binding:"required"`   //密码
	Phone     string `json:"phone" binding:"required"`      //手机
	Email     string `json:"email" binding:"required"`      //邮箱
	EmailCode string `json:"email_code" binding:"required"` //邮箱验证码
}

func Handle_Register(c *gin.Context) {
	appG := app.Gin{C: c}

	var req RegisterReq
	if err := c.ShouldBindJSON(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	userId, ferror := register(&req)
	if ferror.ErrCode != e.SUCCESS {
		if ferror.ErrMsg == "邮箱验证码错误" {
			appG.ResponseReject()
			return
		} else {
			appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
			return
		}
	}

	token, err := util.GenerateToken(cast.ToInt64(userId))
	if err != nil {
		appG.ResponseError(e.ERROR, "创建token失败")
		return
	}

	appG.ResponseSuccess(map[string]string{
		"token": token,
		"phone":req.Phone,
	})
}

func register(req *RegisterReq) (uint64, e.FResult) {
	userInfo, _ := models.GetUserByUserName(req.Username)
	if userInfo != nil && userInfo.ID > 0 {
		return 0, e.FResult{ErrCode: e.ERROR, ErrMsg: "用户名已被注册"}
	}

	userInfo, _ = models.GetUserByPhone(req.Phone)
	if userInfo != nil && userInfo.ID > 0 {
		return 0, e.FResult{ErrCode: e.ERROR, ErrMsg: "手机号已被注册"}
	}

	userInfo, _ = models.GetUserByEmail(req.Email)
	if userInfo != nil && userInfo.ID > 0 {
		return 0, e.FResult{ErrCode: e.ERROR, ErrMsg: "邮箱已被注册"}
	}

	/*
		// 验证：手机验证码、邮箱验证码
		key := fmt.Sprintf("phone:code:%s", req.Phone)
		value, err := gredis.Get(key)
		if err != nil || cast.ToString(value) != req.PhoneCode {
			return 0, e.FResult{ErrCode: e.ERROR, ErrMsg: "手机验证码错误"}
		}
		gredis.Delete(key)
	*/

	key := fmt.Sprintf("email:code:%s", req.Email)
	value, err := gredis.Get(key)
	if err != nil || cast.ToString(value) != req.EmailCode {
		return 0, e.FResult{ErrCode: e.ERROR, ErrMsg: "邮箱验证码错误"}
	}
	gredis.Delete(key)

	var new_user models.User
	new_user.UserName = req.Username
	new_user.Password = util.EncodeMD5(req.Password)
	new_user.Phone = req.Phone
	new_user.Email = req.Email
	new_user.RegisterTime = models.DbTime(time.Now().UTC())
	new_user.UpdateTime = models.DbTime(time.Now().UTC())

	userId, ferror := models.CreateUser(&new_user)
	if ferror.ErrCode != e.SUCCESS {
		return 0, ferror
	}

	return userId, ferror
}

// 发送短信验证码
type SendPhoneCodeReq struct {
	Phone string `form:"phone" binding:"required"`
}

func Handle_SendPhoneCode(c *gin.Context) {
	appG := app.Gin{C: c}

	var req SendPhoneCodeReq
	if err := c.ShouldBindQuery(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	code := util.GenValidateCode(4)
	// 发送短信验证码
	_err := util.SendPhoneCode(req.Phone, setting.PhoneSetting.SignName, setting.PhoneSetting.TemplateCode,
		code, setting.PhoneSetting.AccessKeyID, setting.PhoneSetting.AccessKeySecret)
	if _err != nil {
		appG.ResponseError(e.ERROR, "短信验证码发送错误:"+_err.Error())
		return
	}

	// 保存短信验证码
	key := fmt.Sprintf("phone:code:%s", req.Phone)
	err := gredis.SetSimple(key, code, 300)
	if err != nil {
		appG.ResponseError(e.ERROR, "保存验证码错误:"+err.Error())
		return
	}

	fmt.Printf("phone_code=%s\n", code)

	appG.ResponseSuccess(nil)
}

// 发送邮箱验证码
type SendEmailCodeReq struct {
	Email string `form:"email" binding:"required"`
}

func Handle_SendEmailCode(c *gin.Context) {
	appG := app.Gin{C: c}

	var req SendEmailCodeReq
	if err := c.ShouldBindQuery(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	code := util.GenValidateCode(4)
	// 发送邮箱验证码
	body := fmt.Sprintf("验证码: %v", code)
	err := util.SendMailCode(setting.MailSetting.SmtpHost, setting.MailSetting.SmtpPort,
		setting.MailSetting.Subject, setting.MailSetting.FromName, setting.MailSetting.FromAddress,
		setting.MailSetting.AuthCode, req.Email, body)
	if err != nil {
		appG.ResponseError(e.ERROR, "邮箱验证码发送失败"+err.Error())
		return
	}

	// 保存邮箱验证码
	key := fmt.Sprintf("email:code:%s", req.Email)
	err = gredis.SetSimple(key, code, 300)
	if err != nil {
		appG.ResponseError(e.ERROR, "保存验证码错误:"+err.Error())
		return
	}

	fmt.Printf("email_code=%s\n", code)

	appG.ResponseSuccess(nil)
}

// 用户登录：用户名 + 密码
type LoginWithPwdReq struct {
	Username string `form:"username"  json:"username"binding:"required"`
	Password string `form:"password" json:"password"binding:"required"`
}

func Handle_LoginWithPwd(c *gin.Context) {
	appG := app.Gin{C: c}

	var req LoginWithPwdReq
	if err := c.ShouldBind(&req); err != nil {
		appG.ResponseRejectWithMessage("请求参数错误:"+err.Error())
		return
	}

	userInfo, ferror := models.GetUserByUserName(req.Username)
	if userInfo == nil {
		appG.ResponseRejectWithMessage("用户不存在")
		return
	}
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseRejectWithMessage(ferror.ErrMsg)
		return
	}

	md5_password := util.EncodeMD5(req.Password)
	if md5_password != userInfo.Password {
		appG.ResponseRejectWithMessage("密码错误")
		return
	}

	token, err := util.GenerateToken(cast.ToInt64(userInfo.ID))
	if err != nil {
		appG.ResponseRejectWithMessage("创建token失败")
		return
	}

	appG.ResponseSuccess(map[string]string{
		"token": token,
		"phone":userInfo.Phone,
	})
}

// 用户登录： 手机号 + 短信验证码
type LoginWithPhoneReq struct {
	Phone string `form:"phone" binding:"required"`
	Code  string `form:"code" binding:"required"`
}

func Handle_LoginWithPhone(c *gin.Context) {
	appG := app.Gin{C: c}

	var req LoginWithPhoneReq
	if err := c.ShouldBindQuery(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	userInfo, ferror := models.GetUserByPhone(req.Phone)
	if userInfo == nil {
		appG.ResponseError(e.ERROR, "用户不存在")
		return
	}
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}

	// 获取短信验证码
	key := fmt.Sprintf("phone:code:%s", req.Phone)
	value, err := gredis.Get(key)
	if err != nil || cast.ToString(value) != req.Code {
		appG.ResponseError(e.ERROR, "短信验证码错误")
		return
	}
	gredis.Delete(key)

	token, err := util.GenerateToken(cast.ToInt64(userInfo.ID))
	if err != nil {
		appG.ResponseError(e.ERROR, "创建token失败")
		return
	}

	appG.ResponseSuccess(map[string]string{
		"token": token,
	})
}

// 用户登录： 邮箱 + 邮箱验证码
type LoginWithMailReq struct {
	Email string `form:"email" binding:"required" json:"email"`
	Code  string `form:"code" binding:"required" json:"code"`
}

func Handle_LoginWithEmail(c *gin.Context) {
	appG := app.Gin{C: c}

	var req LoginWithMailReq
	if err := c.ShouldBind(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	userInfo, ferror := models.GetUserByEmail(req.Email)
	if userInfo == nil {
		appG.ResponseError(e.ERROR, "用户不存在")
		return
	}
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}

	// 获取邮箱验证码
	key := fmt.Sprintf("email:code:%s", req.Email)
	value, err := gredis.Get(key)
	if err != nil || cast.ToString(value) != req.Code {
		appG.ResponseError(e.ERROR, "邮箱验证码错误")
		return
	}
	gredis.Delete(key)

	token, err := util.GenerateToken(cast.ToInt64(userInfo.ID))
	if err != nil {
		appG.ResponseError(e.ERROR, "创建token失败")
		return
	}

	appG.ResponseSuccess(map[string]string{
		"token": token,
		"phone": userInfo.Phone,
	})
}

// 获取用户信息
func Handle_GetUserInfo(c *gin.Context) {
	appG := app.Gin{C: c}

	userId := c.GetInt64("user_id")
	userInfo, ferror := models.GetUserById(uint64(userId))
	if userInfo == nil {
		appG.ResponseError(e.ERROR, "用户不存在")
		return
	}
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}

	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}

	userDetail := map[string]interface{}{
		"id":        userInfo.ID,
		"user_name": userInfo.UserName,
		"phone":     userInfo.Phone,
		"email":     userInfo.Email,
	}

	appG.ResponseSuccess(userDetail)
}

// 重置用户密码
type ResetPwdReq struct {
	Email       string `form:"email" binding:"required"`
	Code        string `form:"code" binding:"required"`
	NewPassword string `json:"new_password"`
}

func Handle_ResetPwd(c *gin.Context) {
	appG := app.Gin{C: c}

	var req ResetPwdReq
	if err := c.ShouldBindJSON(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	userInfo, ferror := models.GetUserByEmail(req.Email)
	if userInfo == nil {
		appG.ResponseError(e.ERROR, "用户不存在")
		return
	}
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}

	// 获取邮箱验证码
	key := fmt.Sprintf("email:code:%s", req.Email)
	value, err := gredis.Get(key)
	if err != nil || cast.ToString(value) != req.Code {
		appG.ResponseError(e.ERROR, "邮箱验证码错误")
		return
	}
	gredis.Delete(key)

	newPassword := req.NewPassword
	ferror = models.UpdateUserById(userInfo.ID, map[string]interface{}{
		"password": newPassword,
	})
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(e.ERROR, "重置密码失败")
		return
	}

	appG.ResponseSuccess(nil)
}

// coin价格
func Handle_QueryCoinPrice(c *gin.Context) {
	appG := app.Gin{C: c}

	var rsp RechargeRateRsp
	rsp.Price = setting.CloudPlatformSetting.CoinPrice
	appG.ResponseSuccess(&rsp)
}

type RechargeRateRsp struct {
	Price float64 `json:"price"`
}

// 用户充值
type RechargeReq struct {
	Amount  float64 `json:"amount" binding:"gt=0"`
	Channel int32   `json:"channel" binding:"required"` // 1:alipay   2:paypal
}
